/* useUpload hooks 负责人 zhukai */

import { getToken } from "@/utils/token"
import { ref } from "vue"

interface APIs {
  uploadAPI: string
  mergeAPI?: string
}

/**
 * 这个结合useFileChunk使用
 * 先使用useFileChunk将文件切片，然后使用useUpload上传
 */

export function useUpload(apis: APIs, chunks: any[], signal?: AbortSignal) {
  /* upload */
  const uploadTasks: any[] = []
  const maxUploadCount = 6 // chrome 最大并发数为6
  const progress = ref(0)
  const uploadProgress = ref(0)

  function generateFromData(chunk: any) {
    const formdata = new FormData()
    const keys = Object.keys(chunk)
    for (let i = 0; i < keys.length; i++) formdata.append(keys[i], chunk[keys[i]])
    return formdata
  }

  function uploadChunk(formdata: FormData) {
    const p = fetch(apis.uploadAPI, {
      method: "POST",
      body: formdata,
      headers: {
        token: getToken()
      },
      signal
    })
    return p.then((res) => res?.json())
  }

  async function uploadFile() {
    let currentChunkCount = 0
    let uploadIndex = 0
    while (currentChunkCount < chunks.length) {
      const formdata = generateFromData(chunks[currentChunkCount])
      const task = uploadChunk(formdata)

      task.then(() => {
        uploadIndex++
        uploadTasks.splice(uploadTasks.indexOf(task), 1)
        progress.value = Math.floor((currentChunkCount / chunks.length) * 100)
        uploadProgress.value = Math.floor((uploadIndex / chunks.length) * 100)
      })
      uploadTasks.push(task)

      if (uploadTasks.length === maxUploadCount) await Promise.race(uploadTasks)

      currentChunkCount++
    }

    return await Promise.all(uploadTasks)
  }

  async function mergeFile(data: any) {
    const p = fetch(apis.mergeAPI, {
      method: "POST",
      body: JSON.stringify(data),
      headers: {
        "Content-Type": "application/json"
      }
    })
    return p.then((res) => res.json())
  }

  return {
    uploadFile,
    mergeFile,
    progress,
    uploadProgress
  }
}
